package com.feri.fs.provider.core;

import java.net.URLEncoder;
import java.sql.*;
import java.util.*;

public class DbUtils {
    /**
     * 通过链接，获取数据库的表和表中字段信息
     * @param url 数据库连接地址和端口号
     * @param dbname 数据库名称
     * @param user 数据库用户名
     * @param pass 数据库密码
     * @return 数据库对应的表和字段信息*/
    public static Map<String,Map<String,Map<String,String>>> getDbInfo(String url,String dbname,String user,String pass) throws Exception {
        //1.加载驱动  反射
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2.获取链接
        Connection connection= DriverManager.getConnection("jdbc:mysql://"+url+"/"+dbname+"?serverTimezone=Asia/Shanghai",user,pass);
        //3.获取元数据
        DatabaseMetaData dbmd = connection.getMetaData();
        //4.查询数据库，获取对应库中表
        ResultSet tables = dbmd.getTables(connection.getCatalog(), "%","%",new String[]{"TABLE"});
        //5.创建sql执行对象
        Statement stmt=connection.createStatement();
        Map<String,Map<String,Map<String,String>>> tablesMap=new HashMap<>();
        //6.遍历所有的表
        while (tables.next()) {

            //7.获取表名
            String tableName=tables.getString("TABLE_NAME");
            Map<String,Map<String,String>> fields=new LinkedHashMap<>();
            //8.获取表中的字段信息
            ResultSet rs=stmt.executeQuery("show full columns from " + tableName);

            //9.遍历表中的字段信息
            while (rs.next()){
                //10.记录字段的信息：1.名称 2.数据类型 3.主键 4.备注信息
                Map<String,String> fieldDetail=new LinkedHashMap<>();
                fieldDetail.put("isPK",rs.getString("Key"));
                fieldDetail.put("type",prseType(rs.getString("Type")));
                fieldDetail.put("comment",rs.getString("Comment"));

                fields.put(rs.getString("Field"),fieldDetail);
            }
            tablesMap.put(tableName,fields);
        }
        //11.关闭 释放
        tables.close();
        connection.close();
        return tablesMap;
    }

    /**
     * 实现数据库类型转换为Java类型
     * @param type 数据库数据类型
     * @return 对应的Java数据类型*/
    public static String prseType(String type){
        String t="String";
        if(type.compareToIgnoreCase("bigint")==0){
            t="long";
        }
        else if(type.toLowerCase().contains("int")){
            t="int";
        }else if (type.startsWith("double") || type.startsWith("float") || type.startsWith("decimal")){
            t="double";
        }else if(type.startsWith("date") || type.startsWith("datetime")){
            t="Date";
        }
        return t;
    }

}
